package v1alpha1

import (
	v1 "k8s.io/api/core/v1"
	resource "k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// PDB used to describe PodDisruptionBudget resources in RedisSpec
type PDB struct {
	MinAvailable   *int32 `json:"minAvailable,omitempty"`
	MaxUnavailable *int32 `json:"maxUnavailable,omitempty"`
}

// RedisSpec defines the desired state of Redis
// +k8s:openapi-gen=true
type RedisSpec struct {
	Image            string         `json:"image,omitempty"`      // default redis:latest
	PullPolicy       *v1.PullPolicy `json:"pullPolicy,omitempty"` // default "if not exists"
	SentinelReplicas *int32         `json:"sentinelReplicas"`     // default 3
	RedisReplicas    *int32         `json:"redisReplicas"`        // default 3
	Quorum           int32          `json:"quorum"`               // default 2

	// Persistence options
	// Set volume size if you want persistence or EmptyDir will be used
	PersistentVolumeSize  *resource.Quantity `json:"persistentVolumeSize,omitempty"`  // default empty
	PersistentVolumeClass string             `json:"persistentVolumeClass,omitempty"` // default empty
	// This option purges PVC afrer CR was deleted. Mostly used for development deployments.
	PersistentVolumePurge bool `json:"persistentVolumePurge,omitempty"` // default false

	// Haproxy to make Redis more stable when new master elected
	UseHAProxy                  bool   `json:"useHAProxy,omitempty"`                  // set true to activate HAProxy deployment
	HAProxyImage                string `json:"haproxyImage,omitempty"`                // default haproxy:alpine
	HAProxyReplicas             *int32 `json:"haproxyReplicas,omitempty"`             // default 1
	HAProxyTimeoutServer        int    `json:"haproxyTimeoutServer,omitempty"`        // default 30 (seconds)
	HAProxyTimeoutClient        int    `json:"haproxyTimeoutClient,omitempty"`        // default 30 (seconds)
	HAProxyBackendCheckInterval int    `json:"haproxyBackendCheckInterval,omitempty"` // default 1 (seconds)

	// Manage resources for Sentinel and Redis, use standart Kubernetes specs, default is empty.
	SentinelPodRequests  *v1.ResourceList   `json:"sentinelPodRequests,omitempty"`
	SentinelPodLimits    *v1.ResourceList   `json:"sentinelPodLimits,omitempty"`
	SentinelAffinity     *v1.Affinity       `json:"sentinelAffinity,omitempty"`
	SentinelNodeSelector *map[string]string `json:"sentinelNodeSelector"`
	SentinelTolerations  *[]v1.Toleration   `json:"sentinelTolerations"`

	RedisPodRequests  *v1.ResourceList   `json:"redisPodRequests,omitempty"`
	RedisPodLimits    *v1.ResourceList   `json:"redisPodLimits,omitempty"`
	RedisAffinity     *v1.Affinity       `json:"redisAffinity,omitempty"`
	RedisNodeSelector *map[string]string `json:"redisNodeSelector"`
	RedisTolerations  *[]v1.Toleration   `json:"redisTolerations"`

	// Create PodDisruptionBudget resources for Redis, Sentinel and Haproxy
	PdbRedis    *PDB `json:"pdbRedis,omitempty"`
	PdbSentinel *PDB `json:"pdbSentinel,omitempty"`
	PdbHaproxy  *PDB `json:"pdbHaproxy,omitempty"`
}

// RedisStatus defines the observed state of Redis
// +k8s:openapi-gen=true
type RedisStatus struct {
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Redis is the Schema for the redis API
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
type Redis struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   RedisSpec   `json:"spec,omitempty"`
	Status RedisStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// RedisList contains a list of Redis
type RedisList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []Redis `json:"items"`
}

func init() {
	SchemeBuilder.Register(&Redis{}, &RedisList{})
}
